<template>
  <div class="compact-calendar">
    <div class="calendar-header">
      <h3>{{ currentMonth }}</h3>
      <div class="calendar-controls">
        <el-button-group>
          <el-button size="small" @click="previousMonth">上月</el-button>
          <el-button size="small" @click="goToday">今天</el-button>
          <el-button size="small" @click="nextMonth">下月</el-button>
        </el-button-group>
      </div>
    </div>

    <div class="calendar-body">
      <div class="weekdays-header">
        <div class="weekday" v-for="day in weekdays" :key="day">{{ day }}</div>
      </div>
      <div class="days-grid">
        <div
          v-for="(day, index) in days"
          :key="index"
          class="day-cell"
          :class="{
            'other-month': !day.currentMonth,
            today: isToday(day.date),
            selected: isSelected(day.date),
            'has-event': hasEvent(day.date),
          }"
          @click="selectDate(day.date)"
        >
          <span class="day-number">{{ day.dayNumber }}</span>
          <div v-if="hasEvent(day.date)" class="event-indicator"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'

const props = defineProps({
  value: {
    type: Date,
    default: () => new Date(),
  },
  events: {
    type: Array,
    default: () => [],
  },
})

const emit = defineEmits(['input', 'change'])

const currentDate = ref(new Date(props.value))

// 星期几的本地化显示
const weekdays = ['日', '一', '二', '三', '四', '五', '六']

// 计算当前月份名称
const currentMonth = computed(() => {
  const year = currentDate.value.getFullYear()
  const month = currentDate.value.getMonth() + 1
  return `${year}年${month}月`
})

// 获取当前展示的日历数据 (包括上月和下月的部分日期)
const days = computed(() => {
  const year = currentDate.value.getFullYear()
  const month = currentDate.value.getMonth()

  // 当前月第一天是星期几
  const firstDay = new Date(year, month, 1).getDay()

  // 当前月有多少天
  const daysInMonth = new Date(year, month + 1, 0).getDate()

  // 上个月有多少天
  const daysInPrevMonth = new Date(year, month, 0).getDate()

  const result = []

  // 添加上月的日期
  for (let i = firstDay - 1; i >= 0; i--) {
    const day = daysInPrevMonth - i
    const date = new Date(year, month - 1, day)
    result.push({
      date,
      dayNumber: day,
      currentMonth: false,
    })
  }

  // 添加当前月的日期
  for (let i = 1; i <= daysInMonth; i++) {
    const date = new Date(year, month, i)
    result.push({
      date,
      dayNumber: i,
      currentMonth: true,
    })
  }

  // 添加下月的日期来填满6行网格
  const totalDaysNeeded = 42 // 6行 x 7列
  const remainingDays = totalDaysNeeded - result.length
  for (let i = 1; i <= remainingDays; i++) {
    const date = new Date(year, month + 1, i)
    result.push({
      date,
      dayNumber: i,
      currentMonth: false,
    })
  }

  return result
})

// 检查日期是否是今天
const isToday = (date) => {
  const today = new Date()
  return (
    date.getDate() === today.getDate() &&
    date.getMonth() === today.getMonth() &&
    date.getFullYear() === today.getFullYear()
  )
}

// 检查日期是否被选中
const isSelected = (date) => {
  return (
    date.getDate() === props.value.getDate() &&
    date.getMonth() === props.value.getMonth() &&
    date.getFullYear() === props.value.getFullYear()
  )
}

// 检查日期是否有事件
const hasEvent = (date) => {
  return props.events.some((event) => {
    const eventDate = new Date(event.date)
    return (
      eventDate.getDate() === date.getDate() &&
      eventDate.getMonth() === date.getMonth() &&
      eventDate.getFullYear() === date.getFullYear()
    )
  })
}

// 选择日期
const selectDate = (date) => {
  emit('input', date)
  emit('change', date)
}

// 上个月
const previousMonth = () => {
  const newDate = new Date(currentDate.value)
  newDate.setMonth(newDate.getMonth() - 1)
  currentDate.value = newDate
}

// 下个月
const nextMonth = () => {
  const newDate = new Date(currentDate.value)
  newDate.setMonth(newDate.getMonth() + 1)
  currentDate.value = newDate
}

// 返回今天
const goToday = () => {
  currentDate.value = new Date()
}

// 组件挂载时初始化
onMounted(() => {
  // 如果需要任何初始化逻辑
})
</script>

<style scoped>
.compact-calendar {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  background-color: #fff;
  font-size: 14px;
}

.calendar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #e4e7ed;
}

.calendar-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
}

.weekdays-header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  background-color: #f5f7fa;
  padding: 8px 0;
  border-bottom: 1px solid #e4e7ed;
}

.weekday {
  font-weight: 500;
  color: #606266;
}

.days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-template-rows: repeat(6, auto);
}

.day-cell {
  position: relative;
  height: 32px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  border-bottom: 1px solid #ebeef5;
  border-right: 1px solid #ebeef5;
}

.day-cell:nth-child(7n) {
  border-right: none;
}

.day-cell:nth-last-child(-n + 7) {
  border-bottom: none;
}

.day-number {
  font-size: 13px;
}

.other-month {
  color: #c0c4cc;
}

.today {
  color: #409eff;
  font-weight: bold;
}

.selected {
  background-color: #ecf5ff;
}

.event-indicator {
  position: absolute;
  bottom: 3px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: #409eff;
}

.has-event .day-number {
  color: #409eff;
}
</style>
